﻿#include "common.h"
#include "config_manager.h"
#include <QThread>
#include <QHash>

#include <QSettings>
#include <QDebug>
#include <QMetaObject>
#include <QMutexLocker>

static QMap<QString, QString> m_comdMap;
static QHash<QString, QString> m_queryHash;

Utils *Utils::m_instance = nullptr;
QMutex *Utils::mutex;

Utils::Utils()
{
}

Utils *Utils::instance()
{
    if (m_instance == nullptr) {
        QMutexLocker locker(mutex);
        if (m_instance == nullptr)
            m_instance = new Utils;
    }
    return m_instance;
}

int Utils::getWidgetWidth()
{
    QSettings *setting = ConfigManager::instance()->settings();
    setting->beginGroup("WIND_INFO");
    int val = setting->value("Width").toInt();
    setting->endGroup();
    return val;
}

int Utils::getWidgetHeight()
{
    QSettings *setting = ConfigManager::instance()->settings();
    setting->beginGroup("WIND_INFO");
    int val = setting->value("Height").toInt();
    setting->endGroup();
    return val;
}

QString Utils::resolveDriverPathIO(DeviceInterfaceType type)
{
    QString com("io/serialportboost");
    QString network("io/networkboost");
    QString visa("io/visaio");
#ifdef _MSC_VER
#ifdef QT_DEBUG
    com += "d";
    network += "d";
    visa += "d";
#endif
#endif
    switch (type) {
    case DeviceInterfaceType::COM:
        return com + ".dll";
    case DeviceInterfaceType::LAN:
        return network + ".dll";
    case DeviceInterfaceType::VISA:
        return visa + ".dll";
    default:
        return nullptr;
    }
}

QString Utils::resolveDriverPath(DeviceType type, const QString &libPath)
{
    if (libPath.isEmpty())
        return nullptr;
    QString path = "drivers/";

    switch (type) {
    case DeviceType::SignalGenerator:
        path += STR_DEVICE_TYPE_SignalGenerators;
        break;
    case DeviceType::Amplifier:
        path += STR_DEVICE_TYPE_PowerAmplifiers;
        break;
    case DeviceType::PowerMeter:
        path += STR_DEVICE_TYPE_PowerMeters;
        break;
    case DeviceType::Receiver:
        path += STR_DEVICE_TYPE_Receivers;
        break;
    case DeviceType::SpectrumAnalyzer:
        path += STR_DEVICE_TYPE_SpectrumAnalyzers;
        break;
    case DeviceType::SwitchUnits:
        path += STR_DEVICE_TYPE_SwitchUnits;
        break;
    case DeviceType::FieldProbe:
        path += STR_DEVICE_TYPE_FieldProbes;
        break;
    case DeviceType::CurrentInjectionProbe:
        path += STR_DEVICE_TYPE_GeneralCurrentInjectionProbe;
        break;
    default:
        return nullptr;
    }
    path += "/";
    path += libPath;
    return path;
}

int Utils::findComboBoxIndexByData(QComboBox *cb, int id)
{
    for (int i = 0; i < cb->count(); ++i)
        if (cb->itemData(i).toInt() == id)
            return i;
    return -1;
}

bool Utils::findCalibrationDataByFrequency(const Exec::CalTablePtr &calTable, double freq_Hz, Exec::CalPoint &out)
{
    for (const auto &point : *calTable) {
        if (qFuzzyCompare(point.freq_Hz, freq_Hz)) {
            out = point;
            return true;
        }
    }
    return false;
}

bool Utils::saveLevelScanConfig(const LevelScanningConfig &config)
{
    QSettings *setting = ConfigManager::instance()->settings();
    if (!setting) {
        qWarning() << "QSettings pointer is null in saveLevelScanConfig!";
        return false;
    }
    setting->beginGroup("LEVEL_SCAN_CONFIG");
    setting->setValue("stage", static_cast<int>(config.stage));
    setting->setValue("type", static_cast<int>(config.type));

    setting->setValue("gAttributes.type", static_cast<int>(config.gAttributes.type));
    setting->setValue("gAttributes.InterfaceType", static_cast<int>(config.gAttributes.InterfaceType));
    setting->setValue("gAttributes.InterfaceAddr", config.gAttributes.InterfaceAddr);
    setting->setValue("gAttributes.Model", config.gAttributes.Model);
    setting->setValue("gAttributes.LibraryPath", config.gAttributes.LibraryPath);
    setting->setValue("freqStart_Hz", config.freqStart_Hz);
    setting->setValue("freqStop_Hz", config.freqStop_Hz);
    setting->setValue("freqStep_Hz", config.freqStep_Hz);
    setting->setValue("refLevel", config.refLevel);
    setting->setValue("powerUnit", config.powerUnit);
    setting->setValue("inputAtten", config.inputAtten);
    setting->setValue("dwellTime", config.dwellTime);
    setting->setValue("safetyMargin", config.safetyMargin);
    setting->setValue("factorTableID", config.factorTableID);
    setting->setValue("attTableID", config.attTableID);
    setting->setValue("repeatCont", config.repeatCont);

    setting->endGroup(); // 结束 "LEVEL_SCAN_CONFIG" 组
    setting->sync();     // 立即同步到磁盘 (可选，但推荐)

    return true; // 假设写入总是成功，除非 setting 为空
}

LevelScanningConfig Utils::loadLevelScanConfig()
{
    LevelScanningConfig config; // 创建一个默认构造的 config 对象

    QSettings *setting = ConfigManager::instance()->settings();
    if (!setting) {
        qWarning() << "QSettings pointer is null in loadLevelScanConfig! Returning default config.";
        return config; // 返回默认值
    }

    // 使用与保存时相同的组名
    setting->beginGroup("LEVEL_SCAN_CONFIG");
    bool ok = false; // 用于检查转换是否成功 (可选)
    int stageInt = setting->value("stage", static_cast<int>(TestProcessStage::LevelScanning)).toInt(&ok);
    config.stage = ok ? static_cast<TestProcessStage>(stageInt) : TestProcessStage::LevelScanning;

    int typeInt = setting->value("type", static_cast<int>(HardwareTemplateType::RS)).toInt(&ok);
    config.type = ok ? static_cast<HardwareTemplateType>(typeInt) : HardwareTemplateType::RS;

    config.gAttributes.type = static_cast<DeviceType>(setting->value("gAttributes.type", 0).toInt(&ok));
    config.gAttributes.InterfaceType = static_cast<DeviceInterfaceType>(setting->value("gAttributes.InterfaceType", 0).toInt(&ok));
    config.gAttributes.InterfaceAddr = setting->value("gAttributes.InterfaceAddr", "").toString();
    config.gAttributes.Model = setting->value("gAttributes.Model", "").toString();
    config.gAttributes.LibraryPath = setting->value("gAttributes.LibraryPath", "").toString();

    config.freqStart_Hz = setting->value("freqStart_Hz", config.freqStart_Hz).toDouble();
    config.freqStop_Hz = setting->value("freqStop_Hz", config.freqStop_Hz).toDouble();
    config.freqStep_Hz = setting->value("freqStep_Hz", config.freqStep_Hz).toDouble();
    config.refLevel = setting->value("refLevel", config.refLevel).toDouble();
    config.powerUnit = setting->value("powerUnit", config.powerUnit).toString();
    config.inputAtten = setting->value("inputAtten", config.inputAtten).toDouble();
    config.dwellTime = setting->value("dwellTime", config.dwellTime).toDouble();
    config.safetyMargin = setting->value("safetyMargin", config.safetyMargin).toDouble();
    config.factorTableID = setting->value("factorTableID", config.factorTableID).toInt();
    config.attTableID = setting->value("attTableID", config.attTableID).toInt();
    config.repeatCont = setting->value("repeatCont", config.repeatCont).toInt();

    setting->endGroup();

    return config;
}

QString Utils::loadTemperatureHumiditySensorConfig()
{
    QSettings *setting = ConfigManager::instance()->settings();
    setting->beginGroup("TemperatureHumiditySensor");
    QString add = setting->value("Address").toString();
    if (add.isEmpty()) {
        add = "TCPIP0::127.0.0.1::5889::SOCKET";
        setting->setValue("Address", add);
        setting->sync();
    }
    setting->endGroup();
    return add;
}

QString Utils::getAppLanguage()
{
    QSettings *setting = ConfigManager::instance()->settings();
    setting->beginGroup("APP_CONFIG");
    QString des = setting->value("AppLanguage").toString();
    setting->endGroup();
    if (des.isEmpty()) {
        qWarning() << " AppLanguage get failed, return default value: zh_CN";
        return "zh_CN";
    }
    return des;
}

void Utils::setAppLanguage(const QString &language)
{
    QSettings *setting = ConfigManager::instance()->settings();
    setting->beginGroup("APP_CONFIG");
    setting->setValue("AppLanguage", language);
    setting->endGroup();
    setting->sync();
}

void Utils::saveGeometry(const QRect rect)
{
    QSettings *setting = ConfigManager::instance()->settings();
    setting->beginGroup("WIND_INFO");
    setting->setValue("Geometry", rect);
    setting->endGroup();
    setting->sync();
}

QRect Utils::loadGeometry()
{
    QSettings *setting = ConfigManager::instance()->settings();
    setting->beginGroup("WIND_INFO");
    QRect val = setting->value("Geometry").toRect();
    setting->endGroup();
    return val;
}

void Utils::saveWindowState(const bool isFullScreen)
{
    QSettings *setting = ConfigManager::instance()->settings();
    setting->beginGroup("WIND_INFO");
    setting->setValue("FullScreen", isFullScreen);
    setting->endGroup();
    setting->sync();
}

bool Utils::loadWindowState()
{
    QSettings *setting = ConfigManager::instance()->settings();
    setting->beginGroup("WIND_INFO");
    bool val = setting->value("FullScreen").toBool();
    setting->endGroup();
    return val;
}
